package Email.auto.checker;

import java.awt.AWTException;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;

/**
 * @author Mario Marques
 * @author Helder Lopes
 * 
 */
public class Tray {
	/**
	 * ImageIcon icon : icon showed on each menu item
	 */
	private ImageIcon icon = null; // Icon for menu items
	/**
	 * TrayIcon trayicon: SystemTray icon showed on window tray
	 */
	private TrayIcon trayicon = null;
	/**
	 * SystemTray tray: System Tray reference
	 */
	private SystemTray tray = null;
	/**
	 * JPopupMenu popup: Popup Menu reference
	 */
	private JPopupMenu popup = null;
	/**
	 * JMenuItem menuItemEmailInformation: menu item for Email Information
	 */
	private JMenuItem menuItemEmailInformation = null;
	/**
	 * JMenuItem menuItemVerifyMessg: menu item for option : Verify Emails
	 */
	private JMenuItem menuItemVerifyMessg = null;
	/**
	 * JMenuItem menuItemInsertEmail: menu item for option : Insert Email
	 */
	private JMenuItem menuItemInsertEmail = null;
	/**
	 * JMenuItem menuItemRemoveEmail: menu item for option : Remove Email
	 */
	private JMenuItem menuItemRemoveEmail = null;
	/**
	 * JMenuItem menuItemHide: menu item for option Hide Popup menu
	 */
	private JMenuItem menuItemHide = null;
	/**
	 * JMenuItem menuItemExit: menu item for option exit program
	 */
	private JMenuItem menuItemExit = null;

	/**
	 * JMenu menuItemTimeout: reference for subMenu Select Timeout
	 */
	private JMenu menuItemTimeout = null;

	/**
	 * JRadioButtonMenuItem: reference for each time option
	 */
	private ButtonGroup group = null;
	private JRadioButtonMenuItem timer5 = null;
	private JRadioButtonMenuItem timer10 = null;
	private JRadioButtonMenuItem timer15 = null;
	private JRadioButtonMenuItem timer30 = null;
	private JRadioButtonMenuItem timer45 = null;
	private JRadioButtonMenuItem timer60 = null;
	private JMenuItem timerCostume = null;

	/**
	 * Tray context: reference own tray - to use on an anonimous class
	 */
	private Tray context = null;
	/**
	 * Comunication comunication: reference comunication module
	 */
	private Comunication comunication;
	/**
	 * Account account: reference to active account
	 */
	private Account account = null;
	/**
	 * DESEncryption encryptator: reference to class that encrypt user data
	 */
	private DESEncryption encryptator = null;
	/**
	 * int timerVal: value of current timeout to verify emails
	 */
	private int timerVal;
	/**
	 * Timer t: reference to Timer that counts the amount of time defined
	 */
	private Timer t = null;

	/**
	 * Tray Constructor
	 * 
	 * @param com
	 *            : reference to present comunication module
	 * @param acc
	 *            : reference to active account, this parameter could be null if
	 *            theres any active account
	 * @param des
	 *            : reference to Encryptor / Desencryptor
	 */
	public Tray(Comunication com, Account acc, DESEncryption des) {

		if (com == null || des == null) {
			throw new IllegalArgumentException();
		}

		encryptator = des;
		comunication = com;
		context = this;
		timerVal = ConstComunication.FIFTEEN_MINUTES;
		createObjects(); // Create all main Object
		displayObjects(); // Display all objects created
		account = acc;

		if (account != null) {
			setDataForActualAccount(); // If theres already an account present
										// on system: sets Components accounding
										// that
		}

	}

	/**
	 * Create all basic Visual components with default values for the interface
	 * and define Listeners
	 */
	private void createObjects() {

		trayicon = new TrayIcon(Toolkit.getDefaultToolkit().getImage(
				Tray.class.getResource("images/iconTray.gif")));
		trayicon.addMouseListener(new TrayListener(this));
		tray = SystemTray.getSystemTray();
		popup = new JPopupMenu();

		menuItemEmailInformation = new JMenuItem("No Account");
		menuItemEmailInformation.setEnabled(false);

		icon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(
				getClass().getResource("images/verify.png")));
		menuItemVerifyMessg = new JMenuItem("Verify Unread Messages", icon);
		menuItemVerifyMessg.setEnabled(false);

		icon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(
				getClass().getResource("images/timeout.png")));
		menuItemTimeout = new JMenu("Set Timeout");
		menuItemTimeout.setEnabled(false);

		timer5 = new JRadioButtonMenuItem("5 Minutes");
		timer10 = new JRadioButtonMenuItem("10 Minutes");
		timer15 = new JRadioButtonMenuItem("15 Minutes");
		timer15.setSelected(true);
		timer30 = new JRadioButtonMenuItem("30 Minutes");
		timer45 = new JRadioButtonMenuItem("45 Minutes");
		timer60 = new JRadioButtonMenuItem("60 Minutes");

		timerCostume = new JMenuItem("Set costume timer");

		group = new ButtonGroup();

		icon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(
				getClass().getResource("images/add.png")));

		menuItemInsertEmail = new JMenuItem("Insert Email", icon);
		menuItemInsertEmail.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// Quando se cria o account faz-se logo a a comunicacao com o
				account = new Account(context, comunication);
				account.setVisible();
			}

		});

		icon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(
				getClass().getResource("images/close.png")));
		menuItemRemoveEmail = new JMenuItem("Remove Email", icon);
		menuItemRemoveEmail.setEnabled(false);

		menuItemExit = new JMenuItem("Exit");
		menuItemExit.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (!menuItemEmailInformation.getText().equals("No Account")) {
					String userEmail = account.getEmail();
					String userPass = account.getPass();

					byte[] barray = encryptator.encrypt("" + userEmail + " "
							+ userPass);
					FileOutputStream fout = null;
					try {

						fout = new FileOutputStream(new File("actAccount.dat"));
						System.out.println("O QUE VOU ESCREVER NO FICH: "
								+ barray);
						fout.write(barray);
						fout.flush();

					} catch (FileNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						try {
							fout.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				} else {
					File f = new File("actAccount.dat");
					if (f.exists()) {
						if (f.delete()) {
							System.out.println("Eliminado fich...");
						}
					}
				}
				System.exit(0);
			}
		});

		menuItemHide = new JMenuItem("Hide");
		menuItemHide.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				popup.setVisible(false);
			}
		});

		menuItemRemoveEmail.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				JOptionPane.showMessageDialog(null,
						"Account removed successfully");
				menuItemEmailInformation.setText("No Account");
				menuItemInsertEmail.setEnabled(true);
				menuItemRemoveEmail.setEnabled(false);
				menuItemTimeout.setEnabled(false);
				menuItemVerifyMessg.setEnabled(false);
				comunication.endComunication(account.getDomain());
				t.cancel();
			}
		});

		menuItemVerifyMessg.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.out.println("Unreaded: "
						+ comunication.getUnreadedMessages(account.getDomain()));
				int nMess = comunication.getUnreadedMessages(account
						.getDomain());
				if (nMess > -1) {
					new Notification(account.getEmail(), nMess);
				} else {
					ErrorNotification.showErrorMessage(null,
							ConstErrorNotification.VERIFY_EMAIL_ERROR);
				}
			}
		});

		timerCostume.addActionListener(new ActionListener() {
			// FALTA ACABAR
			@Override
			public void actionPerformed(ActionEvent arg0) {
				String valS = JOptionPane.showInputDialog(null,
						"Set refresh timer (the minimum value is 3 minutes): ",
						15);
				try {
					int val = Integer.parseInt(valS);
					if (val >= 3) {
						setTimer(val * (1000 * 60));
					} else {
						ErrorNotification
								.showErrorMessage(
										null,
										ConstErrorNotification.MINIMUM_TIMEOUT_VALUE_ERROR);
					}
				} catch (NumberFormatException e) {
					ErrorNotification
							.showErrorMessage(
									null,
									ConstErrorNotification.NOT_INTEGER_TIMEOUT_VALUE_ERROR);
				}
			}
		});

		timer5.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				timerVal = ConstComunication.FIVE_MINUTES;
				setTimer(timerVal);
			}
		});

		timer10.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				timerVal = ConstComunication.TEN_MINUTES;
				setTimer(timerVal);
			}
		});

		timer15.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				timerVal = ConstComunication.FIFTEEN_MINUTES;
				setTimer(timerVal);
			}
		});

		timer30.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				timerVal = ConstComunication.THIRTY_MINUTES;
				setTimer(timerVal);
			}
		});

		timer45.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				timerVal = ConstComunication.FORTY_FIVE_MINUTES;
				setTimer(timerVal);
			}
		});

		timer60.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				timerVal = ConstComunication.SIXTY_MINUTES;
				setTimer(timerVal);
			}
		});

	}

	/**
	 * Sets the timer to count the amount of time until verify emails
	 * 
	 * @param timerVal
	 */
	public void setTimer(final int timerVal) {
		if (t != null) {
			t.cancel();
			t = new Timer();
			TimerTask timerControl = new TimerControl(comunication, account);
			System.out.println("TIMERVAL: " + timerVal);
			t.scheduleAtFixedRate(timerControl, timerVal, timerVal);
		}
	}

	/**
	 * Display on screen all visual components created before
	 */
	private void displayObjects() {

		popup.add(menuItemEmailInformation);
		popup.addSeparator();
		popup.add(menuItemVerifyMessg);

		group.add(timer5);
		group.add(timer10);
		group.add(timer15);
		group.add(timer30);
		group.add(timer45);
		group.add(timer60);

		menuItemTimeout.add(timer5);
		menuItemTimeout.add(timer10);
		menuItemTimeout.add(timer15);
		menuItemTimeout.add(timer30);
		menuItemTimeout.add(timer45);
		menuItemTimeout.add(timer60);
		menuItemTimeout.add(timerCostume);

		popup.add(menuItemTimeout);
		popup.addSeparator();
		popup.add(menuItemInsertEmail);
		popup.add(menuItemRemoveEmail);
		popup.addSeparator();
		popup.add(menuItemHide);
		popup.add(menuItemExit);

		try {
			tray.add(trayicon);
		} catch (AWTException e) {
			// new ModError("Cannot access SystemTray");
			System.err.println("Cannot Access System Tray: " + e.toString());
			System.exit(0);
		}

	}

	/**
	 * Set visual details when tray is initialized with an active account
	 */
	private void setDataForActualAccount() {
		getMenuItemEmailInformation().setText(account.getEmail());
		getMenuItemInsertEmail().setEnabled(false);
		getMenuItemRemoveEmail().setEnabled(true);
		getMenuItemTimeout().setEnabled(true);
		getMenuItemVerifyMessg().setEnabled(true);
		getMenuItemTimeout().setEnabled(true);
	}

	/*
	 * GENERATED GETTERS AND SETTER
	 */

	public int getTimerVal() {
		return timerVal;
	}

	public void setTimerVal(int timerVal) {
		this.timerVal = timerVal;
	}

	public ButtonGroup getGroup() {
		return group;
	}

	public void setGroup(ButtonGroup group) {
		this.group = group;
	}

	public JMenuItem getMenuItemVerifyMessg() {
		return menuItemVerifyMessg;
	}

	public void setMenuItemVerifyMessg(JMenuItem menuItemVerifyMessg) {
		this.menuItemVerifyMessg = menuItemVerifyMessg;
	}

	public JMenuItem getMenuItemTimeout() {
		return menuItemTimeout;
	}

	public void setMenuItemTimeout(JMenu menuItemTimeout) {
		this.menuItemTimeout = menuItemTimeout;
	}

	public JMenuItem getMenuItemRemoveEmail() {
		return menuItemRemoveEmail;
	}

	public void setMenuItemRemoveEmail(JMenuItem menuItemRemoveEmail) {
		this.menuItemRemoveEmail = menuItemRemoveEmail;
	}

	public SystemTray getTray() {
		return tray;
	}

	public void setTray(SystemTray tray) {
		this.tray = tray;
	}

	public JPopupMenu getPopup() {
		return popup;
	}

	public void setPopup(JPopupMenu popup) {
		this.popup = popup;
	}

	public JMenuItem getMenuItemEmailInformation() {
		return menuItemEmailInformation;
	}

	public void setMenuItemEmailInformation(JMenuItem menuItemEmailInformation) {
		this.menuItemEmailInformation = menuItemEmailInformation;
	}

	public JMenuItem getMenuItemInsertEmail() {
		return menuItemInsertEmail;
	}

	public void setMenuItemInsertEmail(JMenuItem menuItemInsertEmail) {
		this.menuItemInsertEmail = menuItemInsertEmail;
	}

	public Timer getT() {
		return t;
	}

	public void setT(Timer t) {
		this.t = t;
	}

}
